import {NgModule,Component,ElementRef,OnDestroy,Input,Output,EventEmitter,HostListener,AfterContentInit,
        ContentChildren,ContentChild,QueryList,TemplateRef,EmbeddedViewRef,ViewContainerRef} from '@angular/core';
import {CommonModule} from '@angular/common';
import {SharedModule,PrimeTemplate} from '../common/shared';
import {BlockableUI} from '../common/blockableui';

let idx: number = 0;

@Component({
    selector: '[p-tabViewNav]',
    host:{
        '[class.ui-tabview-nav]': 'true',
        '[class.ui-helper-reset]': 'true',
        '[class.ui-helper-clearfix]': 'true',
        '[class.ui-widget-header]': 'true',
        '[class.ui-corner-all]': 'true'
    },
    styles:[`
    .bg-f1f3f7{background:#f1f3f7 !important} 
    li{margin-right:10px !important;font-size:16px !important;padding: 8px 0 !important;} 
    .active:after{content: '';display: block;width: 100%;height: 2px;background: #fff;bottom: -1px;position: absolute;}
    .ui-tabview-close.fa-close{
        position: absolute;
        right: 0;
        top: 0;
        margin: 0 !important;
        width: 16px;
        height: 16px;
        text-align: center;
        color: #fff;
        background: #c1c1c1;
        border-radius: 50%;
        font-size: 12px;
        line-height: 16px;
        transform: translate(50%,-50%);}
    `],
    template: `
        <ng-template ngFor let-tab [ngForOf]="tabs">
            <li [class]="getDefaultHeaderClass(tab)" [ngStyle]="tab.headerStyle" role="presentation"
                [ngClass]="{'ui-tabview-selected bg-none radius-2 active': tab.selected, 'ui-state-disabled': tab.disabled,'bg-f1f3f7 radius-2':!tab.selected,'relative':true}"
                (click)="clickTab($event,tab)" *ngIf="!tab.closed">
                <a [attr.id]="tab.id + '-label'" href="#" role="tab" [ngClass]="{'color-1a91eb':tab.selected}" [attr.aria-selected]="tab.selected" [attr.aria-controls]="tab.id">
                    <span class="ui-tabview-left-icon fa" [ngClass]="tab.leftIcon" *ngIf="tab.leftIcon" (click)="iconClick($event)"></span>
                    <span class="ui-tabview-title" [ngClass]="{'opacity06':!tab.selected}" >{{tab.header}}</span>
                    <span class="ui-tabview-right-icon fa" [ngClass]="tab.rightIcon" *ngIf="tab.rightIcon" (click)="iconClick($event,tab)"></span>
                </a>
                <span *ngIf="tab.closable" class="ui-tabview-close fa fa-close" (click)="clickClose($event,tab)"></span>
            </li>
        </ng-template>
    `,
})
export class TabViewNav {

    @Input() tabs: TabPanel[];

    @Input() orientation: string = 'top';

    @Output() onTabClick: EventEmitter<any> = new EventEmitter();

    @Output() onTabCloseClick: EventEmitter<any> = new EventEmitter();

    @Output() onIconClick: EventEmitter<any> = new EventEmitter();

    getDefaultHeaderClass(tab:TabPanel) {
        let styleClass = 'ui-state-default ui-corner-' + this.orientation;
        if(tab.headerStyleClass) {
            styleClass = styleClass + " " + tab.headerStyleClass;
        }
        return styleClass;
    }

    clickTab(event, tab: TabPanel) {
        this.onTabClick.emit({
            originalEvent: event,
            tab: tab
        })
    }

    clickClose(event, tab: TabPanel) {
        this.onTabCloseClick.emit({
            originalEvent: event,
            tab: tab
        })
    }

    iconClick(event, tab: TabPanel){
        this.onIconClick.emit({
            originalEvent: event,
            tab: tab
        })
    }
}

@Component({
    selector: 'p-tabPanel',
    template: `
        <div [attr.id]="id" class="ui-tabview-panel p-20 ui-widget-content" [style.display]="selected ? 'block' : 'none'" 
            role="tabpanel" [ngStyle]="contentStyle" [ngClass]="{'border-t-e5e5e5':type,'border-e5e5e5':!type,'p-new-tabview':type == 2}" [attr.aria-hidden]="!selected" [attr.aria-labelledby]="id + '-label'" *ngIf="!closed">
            <ng-content></ng-content>
            <p-templateLoader [template]="contentTemplate" *ngIf="contentTemplate&&(cache ? loaded : selected)"></p-templateLoader>
        </div>
    `
})
export class TabPanel implements AfterContentInit,OnDestroy {

    @Input() type: number = 0;

    @Input() header: string;

    @Input() other: boolean;

    @Input() disabled: boolean;

    @Input() closable: boolean;

    @Input() headerStyle: any;

    @Input() headerStyleClass: string;

    @Input() leftIcon: string;

    @Input() rightIcon: string;

    @Input() cache: boolean = true;

    @ContentChildren(PrimeTemplate) templates: QueryList<any>;

    constructor(public viewContainer: ViewContainerRef) {}

    closed: boolean;

    view: EmbeddedViewRef<any>;

    _selected: boolean;

    loaded: boolean;

    id: string = `ui-tabpanel-${idx++}`;

    contentTemplate: TemplateRef<any>;

    ngAfterContentInit() {
        this.templates.forEach((item) => {
            switch(item.getType()) {
                case 'content':
                    this.contentTemplate = item.template;
                break;

                default:
                    this.contentTemplate = item.template;
                break;
            }
        });
    }

    @Input() get selected(): boolean {
        return this._selected;
    }

    set selected(val: boolean) {
        this._selected = val;
        this.loaded = true;
    }

    ngOnDestroy() {
        this.view = null;
    }
}

@Component({
    selector: 'p-tabView',
    styles:[`ul.p-l-20{padding-left:20px !important}`],
    template: `
        <div [ngClass]="'ui-tabview p-0 ui-widget ui-widget-content ui-corner-all ui-tabview-' + orientation" [ngStyle]="style" [class]="styleClass">
            <ul class="p-0" [ngClass]="{'p-l-20':type == 1}" p-tabViewNav role="tablist" *ngIf="orientation!='bottom'" [tabs]="tabs" [orientation]="orientation" 
                (onTabClick)="open($event.originalEvent, $event.tab)" (onIconClick)="onIconClick.emit({index:findTabIndex($event.tab)})" (onTabCloseClick)="close($event.originalEvent, $event.tab)"></ul>
            <div class="ui-tabview-panels">
                <ng-content></ng-content>
            </div>
            <ul p-tabViewNav role="tablist" *ngIf="orientation=='bottom'" [tabs]="tabs" [orientation]="orientation"
                (onTabClick)="open($event.originalEvent, $event.tab)" (onIconClick)="onIconClick.emit({index:findTabIndex($event.tab)})" (onTabCloseClick)="close($event.originalEvent, $event.tab)"></ul>
        </div>
    `,
})
export class TabView implements AfterContentInit,BlockableUI {

    @Input() orientation: string = 'top';

    @Input() type: number = 0;

    @Input() style: any;

    @Input() styleClass: string;

    @Input() contentStyle: any;

    @Input() controlClose: boolean;

    @Input() controlToggle: boolean;

    @ContentChildren(TabPanel) tabPanels: QueryList<TabPanel>;

    @Output() onChange: EventEmitter<any> = new EventEmitter();

    @Output() onClose: EventEmitter<any> = new EventEmitter();

    @Output() onIconClick: EventEmitter<any> = new EventEmitter();

    @Output() onOhter: EventEmitter<any> = new EventEmitter();

    initialized: boolean;

    tabs: TabPanel[];

    _activeIndex: number;

    _lazy: boolean;

    constructor(public el: ElementRef) {}

    @Input() get lazy(): boolean {
        return this._lazy;
    }

    set lazy(val: boolean) {
        this._lazy = val;
        console.log('Lazy property of TabView is deprecated, use an ngTemplate inside a TabPanel instead for Lazy Loading');
    }

    ngAfterContentInit() {
        this.initTabs();

        this.tabPanels.changes.subscribe(_ => {
            this.initTabs();
        });
    }

    initTabs(): void {
        this.tabs = this.tabPanels.toArray();
        let selectedTab: TabPanel = this.findSelectedTab();
        if(!selectedTab && this.tabs.length) {
            if(this.activeIndex != null && this.tabs.length > this.activeIndex)
                this.tabs[this.activeIndex].selected = true;
            else
                this.tabs[0].selected = true;
        }
    }

    open(event: Event, tab: TabPanel) {
        if(tab.disabled || tab['other']) {
            if(event) {
                event.preventDefault();
            }
            this.onOhter.emit({
                index: this.findTabIndex(tab),
            })
            return;
        }

        if(!tab.selected) {
            if(this.controlToggle){
                this.onChange.emit({
                    originalEvent: event,
                    index: this.findTabIndex(tab),
                    open:()=>{
                        let selectedTab: TabPanel = this.findSelectedTab();
                        if(selectedTab) {
                            selectedTab.selected = false
                        }
                        tab.selected = true;
                    }
                });
            }else{
                let selectedTab: TabPanel = this.findSelectedTab();
                if(selectedTab) {
                    selectedTab.selected = false
                }
                tab.selected = true;
                this.onChange.emit({originalEvent: event, index: this.findTabIndex(tab)});
            }

        }

        if(event) {
            event.preventDefault();
        }
    }

    close(event: Event, tab: TabPanel) {
        if(this.controlClose) {
            this.onClose.emit({
                originalEvent: event,
                index: this.findTabIndex(tab),
                close: () => {
                    this.closeTab(tab);
                }}
            );
        }
        else {
            this.closeTab(tab);
            this.onClose.emit({
                originalEvent: event,
                index: this.findTabIndex(tab)
            });
        }

        event.stopPropagation();
    }

    closeTab(tab: TabPanel) {
        if(tab.selected) {
            tab.selected = false;
            for(let i = 0; i < this.tabs.length; i++) {
                let tabPanel = this.tabs[i];
                if(!tabPanel.closed&&!tab.disabled) {
                    tabPanel.selected = true;
                    break;
                }
            }
        }

        tab.closed = true;
    }

    findSelectedTab() {
        for(let i = 0; i < this.tabs.length; i++) {
            if(this.tabs[i].selected) {
                return this.tabs[i];
            }
        }
        return null;
    }

    findTabIndex(tab: TabPanel) {
        let index = -1;
        for(let i = 0; i < this.tabs.length; i++) {
            if(this.tabs[i] == tab) {
                index = i;
                break;
            }
        }
        return index;
    }

    getBlockableElement(): HTMLElement {
        return this.el.nativeElement.children[0];
    }

    @Input() get activeIndex(): number {
        return this._activeIndex;
    }

    set activeIndex(val:number) {
        this._activeIndex = val;

        if(this.tabs && this.tabs.length && this._activeIndex != null && this.tabs.length > this._activeIndex) {
            this.findSelectedTab().selected = false;
            this.tabs[this._activeIndex].selected = true;
        }
    }
}


@NgModule({
    imports: [CommonModule,SharedModule],
    exports: [TabView,TabPanel,TabViewNav,SharedModule],
    declarations: [TabView,TabPanel,TabViewNav]
})
export class TabViewModule { }
